home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekkan Dennou Club 147
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin
/
games
/
sakiba
/
source
/
screen.c
< prev
next >
Wrap
Text File
|
2000-06-20
|
14KB
|
570 lines
/*********************************************
格闘シミュレーション「さきば」
画面
*********************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys\dos.h>
#include <sys\iocs.h>
#include "sakiba.h"
#include "screen.h"
#include "chranim.h"
#include "pad.h"
#include "pattern.h"
#define SPRITE_FILE "SAKIBA" /* スプライトデータ */
#define CHR_CX 32 /* キャラクタ表示位置 */
#define CHR_Y 100
#define BAR_CX 1 /* 行動バー表示位置 */
#define BAR_Y 128
#define BAR_W 10 /* 1カウントの行動バーの長さ */
#define BAR_H 6
#define BAR_NUM 20 /* 描画するバーの数 */
#define HP_CX 4 /* 体力表示位置 */
#define HP_Y 4
#define HP_H 12 /* 体力バーの高さ */
#define COL_HP 0xffd0 /* 体力バーの色 */
#define COL_DAMAGE 0x27d0 /* ダメージ */
#define COL_BACK 0x1408 /* 下地 */
#define NAME_X 4 /* キャラクタ名表示位置 */
#define NAME_Y 20
#define ACT_X1 4 /* 行動表示位置 */
#define ACT_X2 148
#define ACT_Y 160
#define ACT_H 34
#define MES_CX 128 /* メッセージ表示位置 */
#define MES_CY 64
/*** スプライトコード *****/
#define SPR_HITMARK 0x50d /* ヒットマーク */
#define SPR_CURSOR 0x614 /* 入力カーソル */
static int bar_count; /* 行動バー描画の個数 */
static int message_num; /* 表示メッセージ番号 */
static int hit_count; /* ヒットマーク */
unsigned short* sprite_reg; /* スプライト */
unsigned long anim_count = 0; /* アニメーション用カウンタ */
static COLOR bar_color[ACT_MAX] = { /* 行動バーの色 */
0xe010, /* 防御 */
0xffd8, /* 弱攻撃 */
0xffd8, /* 強攻撃 */
0xfabe, /* 攻撃後の隙 */
0x0708 /* 攻撃を受けた */
};
static unsigned short message[MES_MAX][2] = { /* メッセージ */
{0x400, 4}, /* Ready */
{0x104, 4}, /* Fight! */
{0x108, 3}, /* K.O. */
{0x40b, 2}, /* Win */
{0x210, 2}, /* 1P */
{0x312, 2} /* 2P */
};
/**********************
垂直帰線期間待ち
**********************/
void v_synch(void)
{
pad_synch(); /* パッド同期処理 */
rand(); /* 乱数 */
anim_count++; /* アニメーション用カウンタ */
while ( !(_iocs_b_bpeek((void *)0xe88001) & 0x10) ); /* 垂直帰線期間 */
while ( _iocs_b_bpeek((void *)0xe88001) & 0x10 ); /* 垂直表示期間 */
}
/***************************************
スプライト描画
引数 code = パターンコード
x, y = 描画位置
***************************************/
void put_sprite(CODE code, int x, int y)
{
*sprite_reg++ = (unsigned short)x; /* x座標 */
*sprite_reg++ = (unsigned short)y; /* y座標 */
*sprite_reg++ = code; /* パターンコード */
*sprite_reg++ = 3; /* プライオリティ */
}
/*********************************
文字列描画
引数 str = 文字列
x, y = 描画位置
*********************************/
void draw_str(char* str, short x, short y)
{
struct _symbolptr ptr;
ptr.x1 = x + 1; /* 描画位置 */
ptr.y1 = y + 1;
ptr.string_address = str; /* 文字列 */
ptr.mag_x = 1; /* 倍率 */
ptr.mag_y = 1;
ptr.color = 0x4110; /* 色 */
ptr.font_type = 1; /* 16ドットフォント */
ptr.angle = 0; /* 回転なし */
_iocs_symbol(&ptr);
ptr.x1 = x; /* 描画位置 */
ptr.y1 = y;
ptr.color = 0xffff; /* 色 */
_iocs_symbol(&ptr);
}
/***************************************
メッセージ描画
引数 num = メッセージ番号
x, y = 描画中心位置
***************************************/
void draw_message(int num, short x, short y)
{
CODE code;
int n;
code = (CODE)message[num][0]; /* スプライトコード */
n = (int)message[num][1]; /* 長さ */
x += -n*(16/2) + 16;
y += 16;
for (; n > 0; n--) {
put_sprite(code++, x, y);
x += 16;
}
}
/********************
メッセージ表示
********************/
static
void print_message(void)
{
if ( message_num >= 0 ) {
if ( message_num < MES_1P ) {
draw_message(message_num, MES_CX, MES_CY);
}
else {
draw_message(message_num, MES_CX - 16, MES_CY);
draw_message(MES_WIN, MES_CX + 16, MES_CY);
}
}
}
void draw_bar(int, int, COLOR, COLOR, Bool); /* バー描画 */
/*************************************
行動バー描画
引数 act = 行動
x, y = 描画位置
half = 半分ずらすか
inp = 入力中か
*************************************/
static
void draw_act_bar(ACTION* act, int x, int y, Bool half, Bool inp)
{
ACTION* p;
COLOR col1, col2;
int i, n, cnt;
p = act; /* 行動 */
n = -1;
if ( (cnt = p->count) == 0 ) {
n = 8;
p++;
cnt = p->count;
}
for (i = 0; i < bar_count; i++) {
if ( n < 0 ) { /* 行動表示 */
col1 = bar_color[p->kind];
col2 = (((p->kind == ACT_ATTACK1) || (p->kind == ACT_ATTACK2))
&& (cnt == 1)) ? 0x07c0 : 0x0000;
}
else if ( n > 0 ) { /* 行動非表示 */
col1 = (inp && ((anim_count + n/2)/32 % 2))
? 0x0000 : (COLOR)(((n*3 - 1) << 11) |
((n*3 - 1) << 6) | ((n*3 - 1) << 1));
col2 = 0x0000;
}
else { /* 行動未定 */
col1 = 0x0000;
col2 = 0x0000;
}
if ( half && (i == 0) ) { /* 半分ずらす */
draw_bar(x, y, col1, col2, TRUE);
y += BAR_H/2;
}
else {
draw_bar(x, y, col1, col2, FALSE);
y += BAR_H;
}
if ( n < 0 ) {
if ( --cnt == 0 ) { /* 次の行動 */
if ( (p->kind != ACT_ATTACK1) && (p->kind != ACT_ATTACK2) ) {
p++;
n = ((p->kind >= 0) || (mode == MODE_INPUT)) ? 8 : 0;
}
else {
p++;
cnt = p->count;
}
}
}
else if ( n > 0 ) {
n--;
}
}
}
/**************
体力描画
**************/
static
void draw_hp(void)
{
struct _fillptr ptr;
CHR_PARAM* chr;
short x;
ptr.y1 = HP_Y;
ptr.y2 = HP_Y + HP_H - 1;
chr = &chr_param[PLAYER1]; /* プレイヤー1 */
x = 128 - HP_CX;
if ( chr->hit_point > 0 ) { /* 体力 */
ptr.x1 = x - chr->hit_point;
ptr.x2 = x - 1;
ptr.color = COL_HP;
_iocs_fill(&ptr);
}
if ( chr->hit_point < chr->d_hp ) { /* ダメージ */
ptr.x1 = x - chr->d_hp;
ptr.x2 = x - chr->hit_point - 1;
ptr.color = COL_DAMAGE;
_iocs_fill(&ptr);
if ( anim_count % 2 ) {
chr->d_hp--;
}
}
if ( chr->d_hp < HP_MAX ) { /* 下地 */
ptr.x1 = x - HP_MAX;
ptr.x2 = x - chr->d_hp - 1;
ptr.color = COL_BACK;
_iocs_fill(&ptr);
}
chr = &chr_param[PLAYER2]; /* プレイヤー2 */
x = 128 + HP_CX;
if ( chr->hit_point > 0 ) { /* 体力 */
ptr.x1 = x;
ptr.x2 = x + chr->hit_point - 1;
ptr.color = COL_HP;
_iocs_fill(&ptr);
}
if ( chr->hit_point < chr->d_hp ) { /* ダメージ */
ptr.x1 = x + chr->hit_point;
ptr.x2 = x + chr->d_hp - 1;
ptr.color = COL_DAMAGE;
_iocs_fill(&ptr);
if ( (anim_count % 4) == 0 ) {
chr->d_hp--;
}
}
if ( chr->d_hp < HP_MAX ) { /* 下地 */
ptr.x1 = x + chr->d_hp;
ptr.x2 = x + HP_MAX - 1;
ptr.color = COL_BACK;
_iocs_fill(&ptr);
}
}
/********************
キャラクタ描画
********************/
static
void draw_chr(void)
{
int i, j, k;
if ( mode == MODE_INPUT ) {
put_sprite(SPR_CURSOR + ((anim_count/8) % 3),
(turn == PLAYER1) ? (128 - CHR_CX + 8) : (128 + CHR_CX + 8),
CHR_Y - 20);
/* 入力カーソル描画 */
}
for (i = 0; i < 2; i++) {
for (j = 0; j < 2; j++) {
if ( turn == (i ^ j) ) {
for (k = 0; k < 2; k++) {
draw_pat(&chr_param[j].spr[1 - k], j,
(j == PLAYER1) ? (128 - CHR_CX)
: (128 + CHR_CX),
CHR_Y);
/* キャラクタパターン描画 */
}
}
}
if ( (i == 0) && (hit_count > 0) ) {
put_sprite(SPR_HITMARK + ((hit_count > 12) ? (14 - hit_count) : 2),
(turn == PLAYER1) ? (128 + CHR_CX + 8) : (128 - CHR_CX + 8),
CHR_Y + 8);
/* ヒットマーク描画 */
hit_count--;
}
}
}
/**************
画面描画
**************/
void draw_screen(void)
{
int ssp;
ssp = _iocs_b_super(0); /* スーパーバイザモード */
sprite_reg = SPRITE_REG; /* スプライトレジスタ先頭 */
v_synch(); /* 垂直同期 */
print_message(); /* メッセージ描画 */
draw_chr(); /* キャラクタ描画 */
if ( bar_count < BAR_NUM ) { /* 行動バー描画個数 */
bar_count++;
}
draw_act_bar(chr_param[PLAYER1].action, 128 - BAR_CX - BAR_W, BAR_Y,
(turn != PLAYER1), ((mode == MODE_INPUT) && (turn == PLAYER1)));
draw_act_bar(chr_param[PLAYER2].action, 128 + BAR_CX, BAR_Y,
(turn != PLAYER2), ((mode == MODE_INPUT) && (turn == PLAYER2)));
/* 行動バー描画 */
draw_hp(); /* 体力描画 */
while ( (unsigned long)sprite_reg < (unsigned long)(SPRITE_REG + 4*0x100) ) {
sprite_reg += 3;
*sprite_reg++ = 0; /* スプライト非表示 */
}
_iocs_b_super(ssp); /* ユーザーモード */
}
/**********************************
行動バーを徐々に描画
引数 f = 描画を待つか
**********************************/
void slow_bar(Bool f)
{
bar_count = 0; /* 行動バー描画個数 */
if ( f ) {
while ( bar_count < BAR_NUM ) {
draw_screen(); /* 画面描画 */
if ( esc_key ) {
return;
}
}
}
}
/**************************************
表示メッセージ設定
引数 num = メッセージ番号
**************************************/
void set_message(int num)
{
message_num = num;
}
/**********************
ヒットマーク設定
**********************/
void set_hitmark(void)
{
hit_count = 14;
}
/*********************************************
パターン描画
引数 pat = グラフィックパターン
x, y = 描画位置
*********************************************/
static
void draw_g_pattern(COLOR* pat, short x, short y)
{
struct _putptr ptr;
ptr.x1 = x; /* 描画位置 */
ptr.y1 = y;
ptr.x2 = x + 16 - 1;
ptr.y2 = y + 16 - 1;
ptr.buf_start = pat; /* グラフィックパターン */
ptr.buf_end = pat + 16*16;
_iocs_putgrm(&ptr);
}
/*********************************
行動バー描画(横書き)
引数 x, y = 描画位置
num = 個数
col = 色
*********************************/
static
void draw_bar2(short x, short y, int num, COLOR col)
{
struct _fillptr ptr;
ptr.x1 = x; /* 描画位置 */
ptr.x2 = x + BAR_H - 2;
ptr.y1 = y;
ptr.y2 = y + BAR_W - 1;
ptr.color = col; /* 色 */
for (; num > 0; num--) {
_iocs_fill(&ptr);
ptr.x1 += BAR_H;
ptr.x2 += BAR_H;
}
}
/**********************************
行動描画
引数 num = プレイヤー
**********************************/
static
void draw_action(int num)
{
CHR_DATA* chr;
short x, y;
chr = chr_param[num].data; /* キャラクタデータ */
x = (num == PLAYER1) ? ACT_X1 : ACT_X2;
y = ACT_Y;
draw_g_pattern((num == PLAYER1) ? l_arrow : r_arrow, x, y);
draw_bar2(x + 28, y + 12, GUARD_CNT, bar_color[ACT_GUARD]);
draw_str("防御", x + 18, y); /* 防御 */
y += ACT_H;
draw_g_pattern((num == PLAYER1) ? r_arrow : l_arrow, x, y);
draw_bar2(x + 28, y + 12, chr->attack1.before, bar_color[ACT_ATTACK1]);
draw_bar2(x + 28 + chr->attack1.before*BAR_H, y + 12,
chr->attack1.after, bar_color[ACT_SUKI]);
draw_str(chr->attack1.name, x + 18, y); /* 弱攻撃 */
y += ACT_H;
draw_g_pattern(u_arrow, x, y);
draw_bar2(x + 28, y + 12, chr->attack2.before, bar_color[ACT_ATTACK2]);
draw_bar2(x + 28 + chr->attack2.before*BAR_H, y + 12,
chr->attack2.after, bar_color[ACT_SUKI]);
draw_str(chr->attack2.name, x + 18, y); /* 強攻撃 */
}
/******************
初期画面描画
******************/
void draw_start(void)
{
_iocs_wipe(); /* グラフィッククリア */
draw_str(chr_param[PLAYER1].data->name, NAME_X, NAME_Y);
draw_str(chr_param[PLAYER2].data->name,
256 - NAME_X - strlen(chr_param[PLAYER2].data->name)*8, NAME_Y);
/* キャラクタ名描画 */
draw_action(PLAYER1); /* 行動描画 */
draw_action(PLAYER2);
bar_count = BAR_NUM; /* 行動バー描画個数 */
set_message(-1); /* メッセージ無し */
_iocs_contrast(-2); /* フェードイン */
}
/*****************************************************
スプライトデータ読み込み
引数 sp_name = スプライトファイルネーム
pal_name = パレットファイルネーム
sp = 先頭コード
pal = 先頭パレット
戻り値 0 : 読み込み完了
1 : 読み込み失敗
*****************************************************/
int load_sprite(char* sp_name, char* pal_name, int sp, int pal)
{
FILE* fp;
char *buf, *p;
unsigned short* c;
int i, j, size;
if ( (buf = malloc(0x8000)) == NULL ) {
eprintf("メモリが足りません\n");
return 1;
}
sprintf(buf, "%s.SP", sp_name); /* パターンデータ */
if ( (fp = fopen(buf, "rb")) == NULL ) {
eprintf("パターンファイル \"%s\" が開けません\n", buf);
return 1;
}
size = fread(buf, 0x80, 0x100, fp);
fclose(fp);
for (i = 0, p = buf; i < size; i++, p += 0x80) {
_iocs_sp_defcg(sp++, 1, p); /* スプライト定義 */
}
sprintf(buf, "%s.PAL", pal_name); /* パレットデータ */
if ( (fp = fopen(buf, "rb")) == NULL ) {
eprintf("パレットファイル \"%s\" が開けません\n", buf);
return 1;
}
size = fread(buf, sizeof(short)*0x10, 0x0f, fp);
fclose(fp);
c = (unsigned short*)buf;
for (j = 0; j < size; j++, pal++) {
for (i = 0; i < 0x10; i++) {
_iocs_spalet(i + (1 << 0x1f), pal, (int)*c++);
/* パレット定義 */
}
}
free(buf);
return 0;
}
/********************************
画面初期化
戻り値 0 : 初期化完了
1 : 初期化失敗
********************************/
int init_screen(void)
{
_iocs_contrast(0); /* フェードアウト */
_iocs_sp_init(); /* スプライト画面初期化 */
_iocs_sp_on(); /* スプライト画面表示 */
if ( load_sprite(SPRITE_FILE, SPRITE_FILE, 0x00, 0x01) ) {
/* スプライト読み込み */
return 1;
}
return 0;
}
/************************ End of File *************************************************/